#include "sys_keyAdc.h"
#include "sys_types.h"
#include "sys_uart.h"
#include "sys_interrupt.h"
#include "sys_delay.h"
#include "sys_gpio.h"
#include "sys_io.h"

/*Key_ADC中断*/
void KeyADC_ISR(void)
{
  // 清中断
  int res = 0;
  res = read32(KEYADC_INTS_REG);
  write32(KEYADC_INTS_REG, res);
  if (res & ADC0_KEYDOWN_PENDING) // 按下
  {
  }
  if (res & ADC0_KEYUP_PENDING) // 抬起
  {
  }
  if (res & ADC0_DATA_PENDING) // 数据
  {
  }
}
/*读出AD值*/
int Key_ADC_Read_Value(void)
{
  return (read32(KEYADC_DATA_REG) & 0x3f);
}
/*KEY ADC 初始化*/
void Init_Key_ADC(int mode)
{
  /*变换模式*/
  C_Vlue(KEYADC_CTRL_REG, 12, 0x3);
  S_Vlue(KEYADC_CTRL_REG, 12, mode);
  /*ADC HOLD DIS*/
  //	C_BIT(KEYADC_CTRL_REG,6);
  /*设置UP DOWN 值*/
  C_Vlue(KEYADC_CTRL_REG, 4, 0x3);
  S_Vlue(KEYADC_CTRL_REG, 4, ADC_1_6_V);
  //
#if 0 // 中断开启
    /*使能中断 UP DOWN DATA*/
    S_BIT(KEYADC_INTC_REG,0);//数据中断
    S_BIT(KEYADC_INTC_REG,1);//down中断
    S_BIT(KEYADC_INTC_REG,4);//up中断

    /*设置中断*/
    v3s_interrupt_config(IRQ_LRADC,KeyADC_ISR,0,1);
    global_interrupt_enable();//开IRQ中断
#endif
  /*使能ADC*/
  S_BIT(KEYADC_CTRL_REG, 0);
}
/*通过ADC值返回键值*/
#define OFFSET 4  // 误差值
#define KEY_NUM 6 // 按键数量
__align(0x4)      // 对齐
    int ADC_TAB[KEY_NUM] = {12, 31, 53, 76, 98, 123};
int Find_TAB(int val)
{
  for (int i = 0; i < KEY_NUM; i++)
  {
    if ((val > (ADC_TAB[i] - OFFSET)) && (val < (ADC_TAB[i] + OFFSET)))
      return (i + 1);
  }
  return 0; // 没有比中
}
/*返回键值
mode=0 按下时只返回一次键值
mode=1 按下时一真返回键值
高2位标志：0x80 按下 0x40 抬起
低6位键值：1-63
返回 0，无操作
*/
int KVol = 0;
int Get_ADCKey(int mode)
{
  static int STA = 0;
  static int skey = 0;
  int adc = Key_ADC_Read_Value() & 0x3f;
  KVol = adc * 200 / 63;      // 6位ADC,基准电压2V.放大100倍
  int key = Find_TAB(KVol);   // 按下
  if ((key > 0) & (STA == 0)) // 按下
  {
    STA = 1;
    skey = key; // 保存
    return (key | 0x80);
  }
  else if ((key > 0) & (STA == 1)) // 多次检测按下
  {
    if (mode == 1)
    {
      return (skey | 0x80);
    }
  }
  else if ((key == 0) & (STA == 1)) // 抬起
  {
    int t = (skey | 0x40);
    STA = 2;
    return t;
  }
  else if ((key == 0) & (STA == 2)) // 无操作
  {
    STA = 0;
    return 0;
  }
  return 0;
}

#if 1
/*按键模式*/
void KeyADC_Demo(void)
{
  sysprintf("KeyADC_Demo1\r\n");
  Init_Key_ADC(ADC_NormalMode);
  while (1)
  {
    int key = Get_ADCKey(0);
    // 可以识别的键值
    if ((key & 0x80) && ((key & 0x3f) > 0))
    {
      sysprintf("[KEY%d down] adc=%d\r\n", key & 0xf, KVol);
    }
    if ((key & 0x40) && ((key & 0x3f) > 0))
    {
      sysprintf("[KEY%d up]\r\n", key & 0xf);
    }
    // 未识别的键值
    if ((key & 0x80) && ((key & 0x3f) == 0))
    {
      sysprintf("  [down] adc=%d\r\n", KVol);
    }
    if ((key & 0x40) && ((key & 0x3f) == 0))
    {
      sysprintf("  [up]\r\n");
    }
  }
}
#else
/*ADC模式-6位ADC,基准电压2V
开发板按下按键显示不同电压值，不按下显示最大值(上拉电阻的原因)。
*/
void KeyADC_Demo(void)
{
  sysprintf("KeyADC_Demo2\r\n");
  Init_Key_ADC(ADC_NormalMode);
  while (1)
  {
    delay_ms(200);
    int ADC = Key_ADC_Read_Value() & 0x3f;
    int V = ADC * 200 / 63;                                                              // 6位ADC,基准电压2V.放大100倍
    sysprintf("ADC=%02x Voltage=%d.%d%d\r\n", ADC, V / 100, V % 100 / 10, V % 100 % 10); // 打印ADC值与电压值
  }
}
#endif
